﻿using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support.UI;
using SuuntoAmbitConnector;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EndomondoWebAccess
{
    public class EndomondoWebDriver
    {

        private IWebDriver driver;
        private bool webSiteOpened;

        public enum WebDriverType
        {
            IE,
            Firefox
        }

        private EndomondoWebDriver(IWebDriver driver)
        {
            this.driver = driver;
        }

        public static EndomondoWebDriver Create(WebDriverType webDriverType)
        {
            IWebDriver tmpDriver;

            switch (webDriverType)
            {
                case WebDriverType.IE:
                    tmpDriver = new InternetExplorerDriver();
                    break;
                case WebDriverType.Firefox:
                    tmpDriver = new FirefoxDriver();
                    break;
                default:
                    throw new NotSupportedException();
            }

            // activate implicit waiting for DOM changes
            tmpDriver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));
            
            return new EndomondoWebDriver(tmpDriver);
        }

        public void Close()
        {
            this.driver.Close();
        }

        public void OpenWebSite()
        {
            driver.Navigate().GoToUrl("http://www.endomondo.com/login");
            webSiteOpened = true;
        }

        public void Login()
        {
            
        }

        public bool IsWebSiteOpen()
        {
            return webSiteOpened;
        }

        public Type GetType()
        {
            return driver.GetType(); 
        }

        public void Login(string username, string password)
        {
            OpenWebSite();

            var userNameInputElement = driver.FindElement(By.Name("email"));
            userNameInputElement.SendKeys(username);
            var passwordInputElement = driver.FindElement(By.Name("password"));
            passwordInputElement.SendKeys(password);
            var loginButton = driver.FindElement(By.CssSelector("div.signInButton"));
            loginButton.Click();                        
        }

        public bool IsLoggedIn()
        {
            try
            {
                driver.FindElement(By.CssSelector("div.personalMenu"));
                return true;
            }
            catch (Exception)
            {
                return false;
            }            
        }

        public bool IsManualWorkoutSiteOpen()
        {
            try
            {
                // Verify activity type dropdown is available
                driver.FindElement(By.Name("sport"));
                return true;
            }
            catch (Exception)
            {
                return false;
            }
            
        }

        public void NavigateToManualWorkoutSite()
        {
            driver.Navigate().GoToUrl("http://www.endomondo.com/workouts/create");
            driver.FindElement(By.CssSelector("div.manualWorkout")).Click();
        }

        public bool IsWorkoutCreated(Workout expectedWorkout)
        {
            try
            {
                // Check the endomondo generated workout note against the expected workout comment
                driver.SwitchTo().DefaultContent();

                

                var workoutNotesElement = driver.FindElement(By.Id("workoutNotes")).FindElement(By.TagName("div")).FindElement(By.TagName("p"));
                if (!workoutNotesElement.Text.Equals(expectedWorkout.Comment))
                    return false;


                // Check the endomondo generated workout duration against the expected workout duration
                driver.SwitchTo().DefaultContent();
                                
                var workoutDuration =
                    driver.FindElement(By.CssSelector("div.tab-panel")).FindElement(By.CssSelector("ul.summary")).FindElement(By.CssSelector("li.duration")).FindElement(By.CssSelector("span.value"));

                if (expectedWorkout.GetDurationHourPart() > 0)
                {
                    if (!workoutDuration.Text.Contains(expectedWorkout.GetDurationHourPart().ToString()))
                        return false;
                }
                if (expectedWorkout.GetDurationMinutePart() > 0)
                {
                    if (!workoutDuration.Text.Contains(expectedWorkout.GetDurationMinutePart().ToString()))
                        return false;
                }
                if (expectedWorkout.GetDurationSecondPart() > 0)
                {
                    if (!workoutDuration.Text.Contains(expectedWorkout.GetDurationSecondPart().ToString()))
                        return false;
                }

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public void CreateManualWorkout(Workout expectedWorkout)
        {
            if (!IsManualWorkoutSiteOpen())
                throw new NoSuchWindowException("Manual workout site is not open");

            SelectElement sportsSelector = new SelectElement(driver.FindElement(By.Name("sport")));
            sportsSelector.SelectByValue(EndomondoActivityMapping.GetEndomondoActivityType(expectedWorkout.Activity).ToString());
            SetValueOnElementByName("startTime:dateField", expectedWorkout.StartDate.Date.ToString("yyyy-MM-dd"));
            SetValueOnElementByName("startTime:hoursField", expectedWorkout.StartDate.Hour.ToString());
            SetValueOnElementByName("startTime:minutesField", expectedWorkout.StartDate.Minute.ToString());
            SetValueOnElementByName("distance", (expectedWorkout.DistanceInMeters / 1000).ToString() + "." + (expectedWorkout.DistanceInMeters % 1000).ToString());
            SetValueOnElementByName("duration:hoursField", expectedWorkout.GetDurationHourPart().ToString());
            SetValueOnElementByName("duration:minutesField", expectedWorkout.GetDurationMinutePart().ToString());
            SetValueOnElementByName("duration:secondsField", expectedWorkout.GetDurationSecondPart().ToString());
            SetValueOnElementByName("notes", expectedWorkout.Comment);

            driver.FindElement(By.XPath("//a[contains(@onclick,'okButton')]")).Click();
        }

        private void SetValueOnElementByName(string elementName, string value)
        {
            var element = driver.FindElement(By.Name(elementName));
            element.Clear();
            element.SendKeys(value);
        }



        public void CreateManualWorkout(string ENDOMONDOUSERNAME, string ENDOMONDOPASSWORD, Workout workout)
        {            
            this.Login(ENDOMONDOUSERNAME, ENDOMONDOPASSWORD);
            this.NavigateToManualWorkoutSite();

            this.CreateManualWorkout(workout);
        }
    }
}
